 # -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyKDE4.plasma import Plasma
from PyKDE4 import plasmascript 
from PyKDE4.kdecore import KConfigGroup
from PyKDE4.kdeui import KMessageBox
from PyKDE4.phonon import Phonon
from lastfm import LastFMConnection
from lastfmqt import LastFMConnectionQt
from imageloader import ImageLoader
from widgets import CoverWidget, ControlWidget, SessionWidget

class LastFMPlasmoid(plasmascript.Applet):

	currentTrack = None
	tracks = None
	mediaObject = None
	lastfm = None
	prefetchingPlaylist = False
	cardIndex = 0

	def __init__(self,parent,args=None):

		plasmascript.Applet.__init__(self, parent)

		self.mediaObject = Phonon.createPlayer(Phonon.MusicCategory)
		self.connect(self.mediaObject, SIGNAL('finished()'), self.nextTrack)
		self.connect(self.mediaObject, SIGNAL('stateChanged(Phonon::State, Phonon::State)'), self.handleStateChange)

	def init(self):

		self.setHasConfigurationInterface(True)
		self.theme = Plasma.Svg(self)
		self.theme.setImagePath("widgets/background")
		self.setBackgroundHints(Plasma.Applet.DefaultBackground)

		self.layout = QGraphicsLinearLayout(Qt.Horizontal, self.applet)

		self.covers = CoverWidget(self.applet)
		self.covers.setVisible(False)
		
		self.sessionDialog = SessionWidget(self.applet)
		self.sessionDialog.setVisible(False)

		self.controls = ControlWidget(self.applet)
		self.layout.addItem(self.controls)

		self.setLayout(self.layout)
		self.resize(225, 225)

		self.connect(self.covers, SIGNAL("clicked()"), self.showControls)
		self.connect(self.controls.skip, SIGNAL('clicked()'), self.nextTrack)
		self.connect(self.controls.playStop, SIGNAL('clicked()'), self.playStop)
		self.connect(self.controls, SIGNAL("hoverEnd()"), self.showCovers)
		self.connect(self.sessionDialog.ok, SIGNAL('clicked()'), self.sessionOk)

	def showControls(self):

		self.switchWidgets(self.covers, self.controls)

	def showCovers(self):

		if self.mediaObject.state() != Phonon.PlayingState:

			return

		self.switchWidgets(self.controls, self.covers)

	def showSessionDialog(self, link):

		self.sessionDialog.setLink(link)
		self.switchWidgets(self.controls, self.sessionDialog)

	def sessionOk(self):
	
		self.switchWidgets(self.sessionDialog, self.controls)
		self.requestSession()

	def switchWidgets(self, old, new):

		old.setVisible(False)
		self.layout.removeAt(0)
		self.layout.addItem(new)
		new.setVisible(True)

	def createConnection(self):

		self.lastfm = LastFMConnectionQt()
		self.connect(self.lastfm, SIGNAL('sessionSuccess(QString)'), self.handleSession)
		self.connect(self.lastfm, SIGNAL('sessionFailure(QString)'), self.handleError)
		self.connect(self.lastfm, SIGNAL('tracksSuccess(PyQt_PyObject)'), self.handleTracks)
		self.connect(self.lastfm, SIGNAL('tracksFailure(QString)'), self.handleError)
		self.connect(self.lastfm, SIGNAL('tokenSuccess(QString)'), self.showSessionDialog)
		self.connect(self.lastfm, SIGNAL('tokenFailure(QString)'), self.handleError)
		self.connect(self.lastfm, SIGNAL('stationSuccess()'), self.requestTracks)
		self.connect(self.lastfm, SIGNAL('stationFailure(QString)'), self.handleError)

	def __del__(self):

		self.mediaObject.stop()
	
	def requestSession(self):

		self.lastfm.requestSession() # async

	def requestTracks(self):

		#print 'requestTracks'

		self.setBusy(True)
		self.lastfm.requestTracks() # async

	def handleError(self, message):

		self.setBusy(False)
		KMessageBox.error(None, message, 'last.fm error')

	def handleTracks(self, tracks):

		#print 'handleTracks(), len:', len(tracks)

		for track in tracks:
			track.imageLoader = ImageLoader(track)
			track.imageLoader.load()
			self.connect(track.imageLoader, SIGNAL('success()'), self.covers.update)

		self.setBusy(False)

		self.tracks = tracks
		self.covers.tracks = tracks

		if self.prefetchingPlaylist == True:

			self.prefetchingPlaylist = False;
		else:

			self.playNextTrack()		
	
	def handleSession(self, sessionKey):

		lastfmGroup = self.config().group('lastfm')
		lastfmGroup.writeEntry('sessionkey', sessionKey)
		self.play()

	def handleStateChange(self, new, old):
 
		self.setBusy(False)
		
		if new == Phonon.PlayingState:

			self.controls.playStop.setText('stop')
			self.controls.skip.setEnabled(True)
			self.showCovers()

		elif new == Phonon.StoppedState or new == Phonon.ErrorState:

			self.controls.playStop.setText('play')
			self.controls.skip.setEnabled(False)
			self.showControls()

	def readSessionKey(self):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')

		sessionKey = self.readEntry_hack(lastfmGroup, 'sessionkey', '')

		if sessionKey == '':
			return None
		else:
			return sessionKey

	# Ugly hack to circumvent problems with changing behaviour of the
	# kde python bindings.

	def readEntry_hack(self, group, key, default):

		value = group.readEntry(key, default)

		if isinstance(value, QVariant):

			value = value.toString()

		return value

	def readStation(self):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')

		similarartists = self.readEntry_hack(lastfmGroup, 'similarartists', 'true')

		if similarartists == 'true':
			
			artist = self.readEntry_hack(lastfmGroup, 'similarartists_artist', 'minor threat')
			return 'lastfm://artist/'+artist+'/similarartists'
			
		topfans = self.readEntry_hack(lastfmGroup, 'topfans', 'false')
		if topfans == 'true':

			artist = self.readEntry_hack(lastfmGroup, 'topfans_artist', 'grails')
			return 'lastfm://artist/'+artist+'/fans'

		library = self.readEntry_hack(lastfmGroup, 'library', 'false')
		if library == 'true':
			
			username = self.readEntry_hack(lastfmGroup, 'library_username', '')
			return 'lastfm://user/'+username+'/library'

		neighbours = self.readEntry_hack(lastfmGroup, 'neighbours', 'false')
		if neighbours == 'true':
			
			username = self.readEntry_hack(lastfmGroup, 'neighbours_username', '')
			return 'lastfm://user/'+username+'/neighbours'

		lovedtracks = self.readEntry_hack(lastfmGroup, 'lovedtracks', 'false')
		if lovedtracks == 'true':
			
			username = self.readEntry_hack(lastfmGroup, 'lovedtracks_username', '')
			return 'lastfm://user/'+username+'/loved'

		recommendations = self.readEntry_hack(lastfmGroup, 'recommendations', 'false')
		if recommendations == 'true':
			
			username = self.readEntry_hack(lastfmGroup, 'recommendations_username', '')
			return 'lastfm://user/'+username+'/recommended'

		tag = self.readEntry_hack(lastfmGroup, 'tag', 'false')
		if tag == 'true':
			
			tag = self.readEntry_hack(lastfmGroup, 'tag_tag', 'freak folk')

			return 'lastfm://globaltags/'+tag
		
	def play(self):

		self.createConnection()
		self.setBusy(True)

		# last.fm specific:

		sessionKey = self.readSessionKey()
		if sessionKey == None:

			self.lastfm.requestToken() # async
		else:

			self.lastfm.sessionKey = str(sessionKey)
			self.lastfm.requestStation(str(self.readStation())) # async

	def stop(self):

		self.mediaObject.stop()

	def playStop(self):

		if self.mediaObject.state() != Phonon.PlayingState:

			self.play()
		else:

			self.stop()

	def nextTrack(self):

		self.tracks.remove(self.currentTrack)
		self.playNextTrack()

	def playNextTrack(self):

		#print 'playNextTrack, no of tracks:',  len(self.tracks)

		if len(self.tracks) == 0:
		
			self.requestTracks()
			return

		self.currentTrack = self.tracks[0]
		self.mediaObject.stop()
		self.mediaObject.setCurrentSource(self.currentTrack)

		self.setBusy(True)
		self.mediaObject.play()	# async

def CreateApplet(parent):

	return LastFMPlasmoid(parent)